package com.hhd.flow.configuration;


import com.hhd.flow.engine.FlowEngine;
import com.hhd.flow.engine.cmd.FlowCommandBuilder;
import com.hhd.flow.engine.cmd.FlowCommandExecutor;
import com.hhd.flow.engine.cmd.impl.DefaultFlowCommandBuilder;
import com.hhd.flow.engine.cmd.impl.DefaultFlowCommandExecutor;
import com.hhd.flow.engine.impl.DefaultFlowEngine;
import com.hhd.flow.engine.lisener.FlowProcessEventMultiCaster;
import com.hhd.flow.engine.lisener.impl.DefaultFlowProcessEventMultiCaster;
import com.hhd.flow.engine.res.FlowResourceLoader;
import com.hhd.flow.engine.res.impl.DefaultFlowResourceLoader;
import com.hhd.flow.engine.support.FlowEngineSupport;
import com.hhd.flow.engine.support.FlowFormSupportDelegate;
import com.hhd.flow.engine.variable.FlowVariableLoader;
import com.hhd.flow.engine.variable.impl.DefaultFlowVariableLoader;
import com.tang.script.ScriptEngine;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.annotation.MapperScans;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScans(@MapperScan("com.hhd.**.mapper"))
public class FlowEngineConfiuration {
    @Bean
    @ConditionalOnMissingBean(value = FlowEngine.class)
    FlowEngine flowEngine(ScriptEngine scriptEngine, FlowEngineSupport flowEngineSupport) {
        DefaultFlowEngine flowEngine = new DefaultFlowEngine();

        FlowCommandExecutor flowCommandExecutor = flowCommandExecutor();
        flowCommandExecutor.setFlowEngine(flowEngine);
        flowEngine.setFlowCommandExecutor(flowCommandExecutor);

        flowEngine.setFlowCommandBuilder(flowCommandBuilder());
        flowEngine.setFlowResourceLoader(flowResourceLoader());
        flowEngine.setFlowProcessEventMultiCaster(flowProcessEventMultiCaster());
        flowEngine.setFlowVariableLoader(flowVariableLoader());
        flowEngine.setScriptEngine(scriptEngine);
        flowEngine.setFlowEngineSupport(flowEngineSupport);
        return flowEngine;
    }

    @Bean
    @ConditionalOnMissingBean(value = FlowResourceLoader.class, ignored = FlowEngine.class)
    FlowResourceLoader flowResourceLoader() {
        return new DefaultFlowResourceLoader();
    }

    @Bean
    @ConditionalOnMissingBean(value = FlowCommandExecutor.class, ignored = FlowEngine.class)
    FlowCommandExecutor flowCommandExecutor() {
        return new DefaultFlowCommandExecutor();
    }

    @Bean
    @ConditionalOnMissingBean(value = FlowCommandBuilder.class, ignored = FlowEngine.class)
    FlowCommandBuilder flowCommandBuilder() {
        return new DefaultFlowCommandBuilder();
    }

    @Bean
    @ConditionalOnMissingBean(value = FlowProcessEventMultiCaster.class, ignored = FlowEngine.class)
    FlowProcessEventMultiCaster flowProcessEventMultiCaster() {
        return new DefaultFlowProcessEventMultiCaster();
    }

    @Bean
    @ConditionalOnMissingBean(value = FlowVariableLoader.class, ignored = FlowEngine.class)
    FlowVariableLoader flowVariableLoader() {
        return new DefaultFlowVariableLoader();
    }

    @Bean
    FlowFormSupportDelegate flowFormSupportDelegate() {
        return new FlowFormSupportDelegate();
    }
}
